-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Synchronize files after writing #10735
Conversation
fsync(2) is a somewhat expensive operation that flushes writes to the underlying disk/SSD. It's typically used by databases to ensure that writes survive very hard failure scenarios like your cat kicking the plug out of the wall. Synchronizing isn't automatically done by `flush`ing (from the `std::io::Write` or `tokio::io::AsyncWriteExt` traits). From the [`tokio::fs::File`] moduledocs: > To ensure that a file is closed immediately when it is dropped, you > should call `flush` before dropping it. Note that this does not ensure > that the file has been fully written to disk; the operating system > might keep the changes around in an in-memory buffer. See the > `sync_all` method for telling the OS to write the data to disk. [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
This looks to be what Neovim does too, so it was an oversight on my part: https://github.com/neovim/neovim/blob/4e5c633ed4871a948aff7338b793ac5f93484153/src/nvim/bufwrite.c#L1619-L1634 |
I think we should be calling fsync after restoring the backup since that's where it's called in the linked code. |
I'll be trying this fix. My computers crash or run out of battery pretty often sadly xP |
@kirawi where do you mean? I'm not familiar with the neovim codebase but it looks to me like they're calling fsync after writing and before performing any renaming or permissions/metadata changes |
Oh yeah, you're right. |
fsync(2) is a somewhat expensive operation that flushes writes to the underlying disk/SSD. It's typically used by databases to ensure that writes survive very hard failure scenarios like your cat kicking the plug out of the wall. Synchronizing isn't automatically done by `flush`ing (from the `std::io::Write` or `tokio::io::AsyncWriteExt` traits). From the [`tokio::fs::File`] moduledocs: > To ensure that a file is closed immediately when it is dropped, you > should call `flush` before dropping it. Note that this does not ensure > that the file has been fully written to disk; the operating system > might keep the changes around in an in-memory buffer. See the > `sync_all` method for telling the OS to write the data to disk. [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
fsync(2) is a somewhat expensive operation that flushes writes to the underlying disk/SSD. It's typically used by databases to ensure that writes survive very hard failure scenarios like your cat kicking the plug out of the wall. Synchronizing isn't automatically done by `flush`ing (from the `std::io::Write` or `tokio::io::AsyncWriteExt` traits). From the [`tokio::fs::File`] moduledocs: > To ensure that a file is closed immediately when it is dropped, you > should call `flush` before dropping it. Note that this does not ensure > that the file has been fully written to disk; the operating system > might keep the changes around in an in-memory buffer. See the > `sync_all` method for telling the OS to write the data to disk. [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
fsync(2) is a somewhat expensive operation that flushes writes to the underlying disk/SSD. It's typically used by databases to ensure that writes survive very hard failure scenarios like your cat kicking the plug out of the wall. Synchronizing isn't automatically done by `flush`ing (from the `std::io::Write` or `tokio::io::AsyncWriteExt` traits). From the [`tokio::fs::File`] moduledocs: > To ensure that a file is closed immediately when it is dropped, you > should call `flush` before dropping it. Note that this does not ensure > that the file has been fully written to disk; the operating system > might keep the changes around in an in-memory buffer. See the > `sync_all` method for telling the OS to write the data to disk. [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
@EriKWDev how has this patch been faring for you? I'd be thrilled to hear if you haven't been seeing empty files after your computer dies |
fsync(2) is a somewhat expensive operation that flushes writes to the underlying disk/SSD. It's typically used by databases to ensure that writes survive very hard failure scenarios like your cat kicking the plug out of the wall. Synchronizing isn't automatically done by `flush`ing (from the `std::io::Write` or `tokio::io::AsyncWriteExt` traits). From the [`tokio::fs::File`] moduledocs: > To ensure that a file is closed immediately when it is dropped, you > should call `flush` before dropping it. Note that this does not ensure > that the file has been fully written to disk; the operating system > might keep the changes around in an in-memory buffer. See the > `sync_all` method for telling the OS to write the data to disk. [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
I understand that data preservation is more important than performance, but wouldn't it be better if the |
I wouldn't consider safety-on-quit to be enough. Some people leave the editor open for long stretches and unexpected system failures come at any time. I'm also not convinced this fsyncing would have much impact on an SSD's lifetime. Compared to something like how a database uses fsync, an fsync per |
True. That usually happens to me when I'm "multitasking" (I'm bad at multitasking 😅) |
So does backup work now? I fount Helix two days ago and I found the problem. With NeoVim, you can always undo if you open the file again, but you can't do that with Helix. |
No, that depends on #9154 |
fsync(2) is a somewhat expensive operation that flushes writes to the underlying disk/SSD. It's typically used by databases to ensure that writes survive very hard failure scenarios like your cat kicking the plug out of the wall. Synchronizing isn't automatically done by
flush
ing (from thestd::io::Write
ortokio::io::AsyncWriteExt
traits). From thetokio::fs::File
moduledocs:This seems like a likely fix for #7618 (comment).